/*--------------------------------------------------------------------------------*/
#ifndef __MATH_CURVE_LINEAR__
#define __MATH_CURVE_LINEAR__
/*--------------------------------------------------------------------------------*/
#include "debug.h"
#include "math.h"
#include "math_vector_2.h"
/*--------------------------------------------------------------------------------*/
template < class _CLASS_ >
class MATH_CURVE_LINEAR
{
	// -- PUBLIC

public :

	// .. CONSTRUCTORS

	MATH_CURVE_LINEAR() :
		PointTable(),
		Duration( 0 )
	{
	}

	// .. ACCESSORS

	VOID SetDuration( const REAL & duration )
	{
		Duration = duration;
	}

	// ~~

	const REAL & GetDuration() const
	{
		return Duration;
	}

	// .. INQUIRIES

	_CLASS_ GetValueAtTime(	const REAL & time )
	{
		REAL
			parameter;
		INDEX
			point_index,
			first_point_index,
			second_point_index;

		first_point_index = second_point_index = 0;

		for_each_table_index( point_index, PointTable )
		{
			if( PointTable[ point_index ].Time < time )
			{
				first_point_index = point_index;
			}
			else if( PointTable[ point_index ].Time > time )
			{
				second_point_index = point_index;
				break;
			}
		}

		if( second_point_index <= first_point_index )
		{
			return PointTable[ first_point_index ].Value;
		}

		parameter = ( time - PointTable[ first_point_index ].Time ) / ( PointTable[ second_point_index ].Time - PointTable[ first_point_index ].Time );

		return PointTable[ first_point_index ].Value + ( PointTable[ second_point_index ].Value - PointTable[ first_point_index ].Value ) * parameter;
	}

	// ~~

	_CLASS_ GetValueAtPoint( const INDEX point_index ) const
	{
		return PointTable[ point_index ].Value;
	}

	// .. OPERATIONS

	VOID AddPoint( const REAL & time, const _CLASS_ & value )
	{
		CURVE_POINT
			point;
		point.Time = time;
		point.Value = value;
		PointTable.Add( point );

		SortPointTable();
	}

	// -- PRIVATE

private :

	// .. TYPES

	struct CURVE_POINT
	{
		REAL
			Time;
		_CLASS_
			Value;
	};

	// .. CONSTRUCTORS

	MATH_CURVE_LINEAR( const MATH_CURVE_LINEAR & other );

	// .. OPERATORS

	MATH_CURVE_LINEAR & operator=( const MATH_CURVE_LINEAR & other );

	// .. OPERATIONS

	VOID SortPointTable()
	{
		//PointTable.Sort( ( BOOL ) & MATH_CURVE_LINEAR::CompareCurvePoint );
	}

	// .. FUNCTIONS

	static BOOL CompareCurvePoint( const CURVE_POINT & first, const CURVE_POINT & second )
	{
		return first.Time < second.Time;
	}

	// .. ATTRIBUTES

	ARRAY< CURVE_POINT >
		PointTable;
	REAL
		Duration;
};
#endif
